import router, { dynamicRoutes } from "./router";
import { ElMessage } from "element-plus";
import NProgress from "nprogress";
import "nprogress/nprogress.css";
import { getToken } from "@/utils/auth";
import { isHttp } from "@/utils/validate";
import { isRelogin } from "@/utils/request";
import useUserStore from "@/store/modules/user";
import useSettingsStore from "@/store/modules/settings";
import usePermissionStore from "@/store/modules/permission";
import mapView from "./router/mapView";

NProgress.configure({ showSpinner: false });

export function transListToTreeData(list, rootValue) {
  const arr = [];
  list?.forEach((item) => {
    if (item.pid === rootValue) {
      // 找到了匹配的节点
      // 当前节点的id 和 当前节点的子节点的pid是想等的
      const children = transListToTreeData(list, item.id); // 找到的节点的子节点
      if (children.length) item.children = children; // 将子节点赋值给当前节点
      arr.push(item);
    }
  });
  return arr;
}

const whiteList = ["/login", "/auth-redirect"];
// TODO 导航守卫逻辑，可以根据自己的项目需求修改，不建议随便改
router.beforeEach(async (to, from, next) => {
  NProgress.start();
  // 是否有token
  if (getToken()) {
    // 有token,说明登录了
    // 设置标题
    to.meta.title && useSettingsStore().setTitle(to.meta.title);
    if (to.path === "/login") {
      // 登录了还去登录页，跳转到主页
      next({ path: "/" });
      NProgress.done();
    } else {
      // 登录了，去非登录页，放行
      // 用户资料是否存在，不存在获取一下,
      // TODO 将来这里不一定是通过name来进行判断
      if (!useUserStore().name) {
        isRelogin.show = true;
        // 判断当前用户是否已拉取完user_info信息
        try {
          // // 1、获取用户资料 【有权限需要处理】
          let { menuList } = await useUserStore().getInfo();
          menuList = menuList.map((item) => {
            let arr = item.path.split("/");
            return {
              id: item.id,
              pid: item.pid,
              name: item.name,
              path:
                arr.length === 2
                  ? "/" + arr[arr.length - 1]
                  : arr[arr.length - 1], // 下一级要处理掉 /
              component: mapView[item.name], // 路径
              hidden: item.status !== 1,
              meta: { title: item.title, icon: item.icon },
            };
          });
          menuList = transListToTreeData(menuList, 0);
          console.log(menuList);
          console.log(dynamicRoutes);
          // const result = transListToTreeData(menuList, 0)
          // console.log(result)

          // **********************************************
          // 加载视图的判断
          // const loadView = (str) => {
          //   try {
          //     if (str === "layout") {
          //       return layout;
          //     } else if (str === "content/article/info") {
          //       return require(`@/views/${str}.vue`).default;
          //     } else {
          //       return require(`@/views/${str}/index.vue`).default;
          //     }
          //   } catch (error) {
          //     console.log(error);
          //     return require(`@/views/notpl.vue`).default;
          //   }
          // };
          // // 处理数据
          // let result = menuList.map((item) => {
          //   let obj = {};
          //   obj.path = item.path;
          //   obj.name = item.name;
          //   obj.meta = { title: item.title, icon: item.icon };
          //   if (item.redirect) {
          //     obj.redirect = item.redirect;
          //   }
          //   obj.component = loadView(item.path);
          //   obj.id = item.id;
          //   obj.pid = item.pid;
          //   return obj;
          // });
          // result = transListToTreeData(result, 0);

          // // 2 如果项目中有权限处理要处理执行  【服务器端返回动态路由实例】
          let accessRoutes = await usePermissionStore().generateRoutes(
            menuList
          );

          // 1、获取用户资料 【没有权限需要处理】
          // await useUserStore().getInfo()
          // 2、 如果项目没有权限要处理  【没有权限需要处理，本地配置路由】
          // let accessRoutes = await usePermissionStore().localRoutes()
          // console.log(accessRoutes)
          // ================无论是本地配置还是服务器端返回都要动态路由都要添加到路由实例中去==================
          // 3、添加到路由实例中去，由于vue-router4已经抛弃了addRoutes方法，现在需要使用addRoute方法
          accessRoutes.forEach((route) => {
            if (!isHttp(route.path)) {
              router.addRoute(route); // 动态添加可访问路由表
            }
          });
          // next(to.path)
          next({ ...to, replace: true }); // hack方法 确保addRoutes已完成
        } catch (error) {
          console.log(error);
          // 拉取用户资料失败，退出
          await useUserStore().logOut();
          // ElMessage.error(error)
          next({ path: "/" });
        }
      } else {
        // 已经有了用户资料放行
        next();
      }
    }
  } else {
    // 没有token，没有登录
    if (whiteList.indexOf(to.path) !== -1) {
      // 在免登录白名单，直接进入
      next();
    } else {
      next(`/login?redirect=${to.fullPath}`); // 否则全部重定向到登录页
      NProgress.done();
    }
  }
});

router.afterEach(() => {
  NProgress.done();
});
